<template>
    <view class="u-input u-border item" @tap="show = true">
        <view class="l-select-label">
            {{ label }}
        </view>
        <view class="flex-1 ml-2">
            {{ showText }}
            <text class="text-gray-400" v-if="!showText">{{ placeholder }}</text>
        </view>
        <u-icon name="arrow-down"></u-icon>
    </view>

    <u-picker closeOnClickOverlay :defaultIndex="currentIndexs" :show="show" :keyName="'label'" @cancel="show = false"
        @close="show = false" :columns="showList" @confirm="confirm" @change="changeHandler"></u-picker>
</template>
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
type List = Array<{ label: string, value: any, children?: List }>
type ModelValue = Array<number | string> | string
let props = withDefaults(defineProps<{
    label?: string,
    modelValue?: ModelValue,
    placeholder?: string,
    list: List,
    returnType: 'list' | 'string'
}>(), {
    placeholder: '请选择',
    list: () => [],
    modelValue: '',
    returnType: 'list'
})

// 获取下标组
let getIdxs = (list: List, vas: any[]) => {
    if (vas.length != getLen(list)) return new Array(getLen(props.list)).fill(0);
    return list.reduce((previousValue, currentValue, currentIndex) => {
        return previousValue.push(list.findIndex(item => item.value == vas[currentIndex]))
    }, [] as any)
}
// 获取选择列表
const getList = (list: List, ids: Array<any>): any[] => {
    if (ids.length != getLen(list)) return [];
    return ids?.reduce((previousValue, currentValue, currentIndex) => {
        if (currentIndex != ids?.length - 1) {
            previousValue.push(previousValue[previousValue.length - 1][currentValue]?.children)
        }
        return previousValue
    }, [list])
}
// 获取value组
let getValues = (list: List, ids: any[]) => {
    if (ids.length != getLen(list)) return [];
    return getList(list, ids).reduce((previousValue, currentValue, currentIndex) => {
        return previousValue.push(list[ids[currentIndex]])
    }, [] as any[])
}
// 获取当前的文字
const getText = (list: List, idx: Array<any>) => {
    if (idx.length != getLen(list)) return '';
    return getList(list, idx).reduce((previousStr, currentValue, currentIndex) => {
        if (currentValue[idx[currentIndex]]) return previousStr + ' ' + currentValue[idx[currentIndex]]?.label;
        return previousStr + ''
    }, '')
};

// 获取数组展开长度
const getLen = (list: List) => {
    let maxLen = 0
    const call = (list: List, len = 1) => {
        maxLen = Math.max(maxLen, len)
        list.forEach(element => {
            element.children && call(element.children, len + 1)
        });
    }
    call(list)
    return maxLen;
}


const emit = defineEmits(['update:modelValue']);
const show = ref(false), currentIndexs = ref(getIdxs(props.list, typeof props.modelValue == 'string' ? [] : props.modelValue));

watch(() => props.list, () => {
    let vas = typeof props.modelValue == 'string' ? [] : props.modelValue;
    currentIndexs.value = getIdxs(props.list, vas)
})
watch(() => props.modelValue, () => {
    if (typeof props.modelValue != 'string' && props.modelValue) {
        currentIndexs.value = getIdxs(props.list, props.modelValue)
    }
})

// 显示的列表
const showList = computed(() => {
    return getList(props.list, currentIndexs.value)
})
// 确定
function confirm(res: any) {
    show.value = false;
    currentIndexs.value = res.indexs
    emit('update:modelValue', props.returnType == 'list' ? getValues(props.list, res.indexs) : getText(props.list, res.indexs));
}
// 滑动
function changeHandler({ columnIndex, index }: { columnIndex: number, index: number, values: Array<number> }) {
    currentIndexs.value = currentIndexs.value.map((item: any, idx: any) => {
        if (idx < columnIndex) return item;
        if (columnIndex == idx) return index;
        return 0
    })
}

// 显示文字
const showText = computed(() => {
    if (props.returnType == 'string') return props.modelValue;
    if (props.modelValue?.length && showList.value.length && typeof props.modelValue != 'string') {
        let ids = getIdxs(props.list, props.modelValue)
        return getText(props.list, ids);
    }
    return ''
})
</script>
<style scoped lang="scss">
.item {
    @apply rounded h-[24px] py-[6px] px-[9px] flex items-center box-content;
}
</style>
<style lang="scss">
l-selects {
    @apply block;
}
</style>